package dlb.busstop.json;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.location.Location;
import dlb.busstop.data.BusStop;
import dlb.busstop.data.BusinessObjectFactory;
import dlb.busstop.utils.ServiceProvider;

public abstract class BusStopListGrabber {

	public static BusStopListGrabber getInstance(JSONParser parser) {
		return getInstance(parser, ServiceProvider.getInstance());
	}

	public static BusStopListGrabber getInstance(JSONParser parser,
			ServiceProvider provider) {
		return new BusStopListGrabberImpl(parser, provider);
	}

	public abstract JSONArray grabBusStopJSONArray(Location location,
			int quantity, String searchKey) throws JSONException, IOException;

	public abstract List<BusStop> grabBusStopList(Location location,
			int quantity, String searchKey) throws JSONException, IOException;

	static class BusStopListGrabberImpl extends BusStopListGrabber {

		private JSONParser parser;
		private ServiceProvider provider;

		BusStopListGrabberImpl(JSONParser parser, ServiceProvider provider) {
			this.parser = parser;
			this.provider = provider;
		}

		@Override
		public JSONArray grabBusStopJSONArray(Location location, int quantity,
				String searchKey) throws JSONException, IOException {
			JSONObject rawJson = null;
			String url ="";
			if (searchKey == null) {
				double lat = location.getLatitude();
				double lon = location.getLongitude();
						url = provider.getProtocol() + "://"
						+ provider.getHost() + ":" + provider.getPort() + "/"
						+ provider.getResourceUrl() + "/GetNearestStops?"
						+ "latitude=" + lat + "&" + "longitude=" + lon
						+ "&psw=" + provider.getPassword() + "&" + "quantity="
						+ quantity;
						rawJson = parser.parse(url);		
				if (rawJson.get("d").equals(JSONObject.NULL)) {
					return null;
				}
			}
			else {
				url = provider.getProtocol() + "://"
						+ provider.getHost() + ":" + provider.getPort() + "/"
						+ provider.getResourceUrl() + "/GetAddressesBySubtring?"
						+ "address=" + URLEncoder.encode(searchKey, "UTF-8")
						+ "&psw=" + provider.getPassword();
						rawJson = parser.parse(url);
				if (rawJson.get("d").equals(JSONObject.NULL)) {
					return null;
				}
			}
			return rawJson.getJSONArray("d");
		}

		@Override
		public synchronized List<BusStop> grabBusStopList(Location location, int quantity, String searchKey)
				throws JSONException, IOException {
			JSONArray busStopArray = grabBusStopJSONArray(location, quantity, searchKey);
			if (busStopArray == null) {
				return null;
			}
			int length = busStopArray.length();
			List<BusStop> stops = new ArrayList<BusStop>(length);
			BusStop stop;
			JSONObject stopJson;
			for (int i = 0; i < length; i++) {
				stopJson = busStopArray.getJSONObject(i);
				stop = BusinessObjectFactory.createBusStopFromJSON(stopJson);
				stops.add(stop);
			}
			return stops;
		}
	}
}
